package top.lixunda.ecommerce.server.user.api.entity.dto;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.google.common.collect.ImmutableMap;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.experimental.Accessors;
import top.lixunda.common.utils.ObjectValidators;
import top.lixunda.ecommerce.server.business.api.condition.ILambdaQueryWrapperDTO;
import top.lixunda.ecommerce.server.business.api.entity.dto.OrderByDTO;
import top.lixunda.ecommerce.server.user.api.entity.db.MessageDO;

import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * 消息查询DTO
 *
 * @author lixunda
 * @version time:2020/4/12 0:44
 */
@ApiModel("消息查询DTO")
@Data
@EqualsAndHashCode(callSuper = false)
@Accessors(chain = true)
public class MessageQueryDTO extends OrderByDTO
        implements ILambdaQueryWrapperDTO<MessageDO> {

    /**
     * 搜索字段
     */
    @ApiModelProperty("搜索字段")
    private List<String> search;

    /**
     * 消息编号
     */
    @ApiModelProperty("消息编号")
    private List<Integer> id;

    /**
     * 消息接收用户类型
     */
    @ApiModelProperty("消息接收用户类型")
    private List<String> userType;

    /**
     * 消息接收用户名称
     */
    @ApiModelProperty("消息接收用户名称")
    private List<String> userName;

    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeBegin;
    /**
     * 创建时间
     */
    @ApiModelProperty("创建时间")
    private LocalDateTime createTimeEnd;

    /**
     * 消息产生人员编号
     */
    @ApiModelProperty("消息产生人员编号")
    private List<Integer> createUserId;

    /**
     * 消息类型，如系统通知
     */
    @ApiModelProperty("消息类型，如系统通知")
    private List<String> messageType;

    /**
     * 消息标题
     */
    @ApiModelProperty("消息标题")
    private List<String> messageTitle;

    /**
     * 任务编号
     */
    @ApiModelProperty("任务编号")
    private List<Integer> taskId;

    /**
     * 个人任务编号
     */
    @ApiModelProperty("个人任务编号")
    private List<Integer> taskItemId;

    /**
     * 业务编号
     */
    @ApiModelProperty("业务编号")
    private List<Integer> businessId;

    /**
     * 消息是否被消费 0 未消费 1 已消费
     */
    @ApiModelProperty("消息是否被消费 0 未消费 1 已消费")
    private List<Integer> consumeFlag;

    /**
     * 消费方式，查看消费和一键消费
     */
    @ApiModelProperty("消费方式，查看消费和一键消费")
    private List<String> consumeType;

    /**
     * 消费时间
     */
    @ApiModelProperty("消费时间")
    private LocalDateTime consumeTimeBegin;

    /**
     * 消费时间
     */
    @ApiModelProperty("消费时间")
    private LocalDateTime consumeTimeEnd;

    /**
     * 自定义参数1
     */
    @ApiModelProperty("自定义参数1")
    private List<String> param1;

    /**
     * 自定义参数2
     */
    @ApiModelProperty("自定义参数2")
    private List<String> param2;

    /**
     * 自定义参数3
     */
    @ApiModelProperty("自定义参数3")
    private List<String> param3;

    /**
     * 排序字段
     */
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    private static final Map<String, SFunction<MessageDO, ?>> MESSAGE_COLUMNS =
            new ImmutableMap.Builder<String, SFunction<MessageDO, ?>>()
                    .put("id", MessageDO::getId)
                    .put("userId", MessageDO::getUserId)
                    .put("userType", MessageDO::getUserType)
                    .put("userName", MessageDO::getUserName)
                    .put("createTime", MessageDO::getCreateTime)
                    .put("createUserId", MessageDO::getCreateUserId)
                    .put("createUserType", MessageDO::getCreateUserType)
                    .put("createUserName", MessageDO::getCreateUserName)
                    .put("messageType", MessageDO::getMessageType)
                    .put("messageTitle", MessageDO::getMessageTitle)
                    .put("messageContent", MessageDO::getMessageContent)
                    .put("messageUrl", MessageDO::getMessageUrl)
                    .put("taskId", MessageDO::getTaskId)
                    .put("taskItemId", MessageDO::getTaskItemId)
                    .put("businessId", MessageDO::getBusinessId)
                    .put("consumeFlag", MessageDO::getConsumeFlag)
                    .put("consumeType", MessageDO::getConsumeType)
                    .put("consumeTime", MessageDO::getConsumeTime)
                    .put("param1", MessageDO::getParam1)
                    .put("param2", MessageDO::getParam2)
                    .put("param3", MessageDO::getParam3)
                    .build();

    /**
     * 将当前用于查询的DTO中的查询数据转换为 LambdaQuerySqlWrapper
     *
     * @return 条件构造器 LambdaQuerySqlWrapper
     */
    @SuppressWarnings("AlibabaMethodTooLong")
    @Override
    @ApiModelProperty(hidden = true)
    @JsonIgnore
    public LambdaQueryWrapper<MessageDO> toWrapper() {
        LambdaQueryWrapper<MessageDO> wrapper = new LambdaQueryWrapper<>();
        if (ObjectValidators.isNotEmpty(search)) {
            wrapper.and(innerWrapper -> search.forEach(item ->
                    innerWrapper.or().like(MessageDO::getMessageTitle, item)
                            .or().like(MessageDO::getMessageContent, item)
                            .or().like(MessageDO::getCreateUserName, item)));
        }
        if (ObjectValidators.isNotEmpty(id)) {
            wrapper.and(innerWrapper -> id.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getId, item)));
        }
        if (ObjectValidators.isNotEmpty(userType)) {
            wrapper.and(innerWrapper -> userType.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getUserType, item)));
        }
        if (ObjectValidators.isNotEmpty(userName)) {
            wrapper.and(innerWrapper -> userName.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getUserName, item)));
        }
        if (ObjectValidators.isNotEmpty(createTimeBegin)) {
            wrapper.ge(MessageDO::getCreateTime, createTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(createTimeEnd)) {
            wrapper.le(MessageDO::getCreateTime, createTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(createUserId)) {
            wrapper.and(innerWrapper -> createUserId.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getCreateUserId, item)));
        }
        if (ObjectValidators.isNotEmpty(messageType)) {
            wrapper.and(innerWrapper -> messageType.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getMessageType, item)));
        }
        if (ObjectValidators.isNotEmpty(messageTitle)) {
            wrapper.and(innerWrapper -> messageTitle.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getMessageTitle, item)));
        }
        if (ObjectValidators.isNotEmpty(taskId)) {
            wrapper.and(innerWrapper -> taskId.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getTaskId, item)));
        }
        if (ObjectValidators.isNotEmpty(taskItemId)) {
            wrapper.and(innerWrapper -> taskItemId.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getTaskItemId, item)));
        }
        if (ObjectValidators.isNotEmpty(businessId)) {
            wrapper.and(innerWrapper -> businessId.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getBusinessId, item)));
        }
        if (ObjectValidators.isNotEmpty(consumeFlag)) {
            wrapper.and(innerWrapper -> consumeFlag.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getConsumeFlag, item)));
        }
        if (ObjectValidators.isNotEmpty(consumeType)) {
            wrapper.and(innerWrapper -> consumeType.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getConsumeType, item)));
        }
        if (ObjectValidators.isNotEmpty(consumeTimeBegin)) {
            wrapper.ge(MessageDO::getConsumeTime, consumeTimeBegin);
        }
        if (ObjectValidators.isNotEmpty(consumeTimeEnd)) {
            wrapper.le(MessageDO::getConsumeTime, consumeTimeEnd);
        }
        if (ObjectValidators.isNotEmpty(param1)) {
            wrapper.and(innerWrapper -> param1.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getParam1, item)));
        }
        if (ObjectValidators.isNotEmpty(param2)) {
            wrapper.and(innerWrapper -> param2.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getParam2, item)));
        }
        if (ObjectValidators.isNotEmpty(param3)) {
            wrapper.and(innerWrapper -> param3.forEach(item ->
                    innerWrapper.or().eq(MessageDO::getParam3, item)));
        }
        dealWithOrderBy(wrapper, MESSAGE_COLUMNS);
        return wrapper;
    }
}
